/*
 * $Id: StatusReportHelper.java,v 1.9 2009/07/24 18:34:02 oliver Exp $
 * 
 * Copyright (C) 2008 General Electric Company. All Rights Reserved.
 * 
 * This software is the confidential and proprietary information of the General
 * Electric Company (GE). You shall not disclose this software and shall use it
 * only in accordance with the terms of the license agreement you entered into
 * with GE.
 * 
 * GE MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
 * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
 * NON-INFRINGEMENT. GE SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
 * AS A RESULT OF USING, MODIFYING, OR DISTRIBUTING THIS SOFTWARE OR ITS
 * DERIVATIVES.
 */
package com.ge.healthcare.autosc.onwatch.util;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import org.springframework.util.Assert;
import org.xml.sax.SAXException;

import com.ge.healthcare.autosc.common.ASCLogger;
import com.ge.healthcare.autosc.common.database.dao.IOnwatchTaskDAO;
import com.ge.healthcare.autosc.common.database.pojo.ActOnwatchTask;
import com.ge.healthcare.autosc.common.database.pojo.CfgXmlParserInfo;
import com.ge.healthcare.autosc.common.util.ApplicationInfo;
import com.ge.healthcare.autosc.common.util.PropertyConstants;
import com.ge.healthcare.autosc.common.util.TimeFormatStandard;
import com.ge.healthcare.autosc.onwatch.exception.StatusReportHelperException;
import com.ge.healthcare.autosc.onwatch.exception.XmlParserFactoryException;
import com.ge.healthcare.autosc.onwatch.xml.parser.IXmlParser;
import com.ge.healthcare.autosc.onwatch.xml.parser.XmlParserFactory;
import com.ge.healthcare.autosc.onwatch.xml.tag.ResultTag;
import com.ge.healthcare.autosc.onwatch.xml.tag.StatusReport;
import com.ge.healthcare.autosc.onwatch.xml.tag.TaskInfoTag;
import com.ge.healthcare.autosc.onwatch.xml.tag.TaskListTag;
import com.ge.healthcare.autosc.onwatch.xml.tag.TaskResultStatusTag;
import com.ge.healthcare.autosc.onwatch.xml.tag.TaskResultTag;
/**
 * This is a helper class to constructperform operations against information in
 * the StatusReport object.
 * 
 * @author 212042946
 *
 */
public class StatusReportHelper {

	private static IOnwatchTaskDAO onwatchTaskDAO = null;

	/**
	 * Init method (Spring init)
	 */
	public void init() {
		Assert.notNull(onwatchTaskDAO, 
			"ActOnwatchTaskDAO is not defined. Use setActOnwatchTaskDAO to provide one");
	}
	
	/**
	 * Build StatusReport object from a StatusReport XML file
	 * @param dir Directory where the StatusReport is located	
	 * @return	StatusReport object
	 * @throws StatusReportHelperException
	 */
	public static StatusReport getStatusReport(File dir)
		throws StatusReportHelperException {
		StatusReport statusReport = null;
		try {
			IXmlParser parser = XmlParserFactory.getXmlParser(CfgXmlParserInfo.STATUS_REPORT);
			String fName = ApplicationInfo.getInstance()
				.getProperty(PropertyConstants.ONWATCH_STATUS_REPORT_FILE_NAME, "iipStatusReport.xml");
			File statusReportFile = new File(dir, fName);
			System.out.println("Parsing report " + statusReportFile.getPath());
			statusReport = (StatusReport)parser.processResponse(statusReportFile);
			OnWatchLogger.addStepLog("Successfully parsed status report");
		} catch (XmlParserFactoryException xpfe) {
			String errorStr = "Error creating XML parser to process status report";
			throw new StatusReportHelperException(errorStr, xpfe, OnWatchCodeConstants.PRC_F_OWR_014);
		} catch (SAXException se) {
			String errorStr = "Error parsing the status report. Status report may have invalid format";
			throw new StatusReportHelperException(errorStr, se, OnWatchCodeConstants.PRC_F_OWR_013);
		} catch (IOException ioe) {
			String errorStr = "Error parsing the status report because of IO error";
			throw new StatusReportHelperException(errorStr, ioe, OnWatchCodeConstants.PRC_F_OWR_015);
		}
		return statusReport;
	}

	/**
	 * Retrieve the StatusReport object for the Onwatch task and
	 * update its corresponding record in the database with
	 * the given information in the StatusReport object.
	 * @param statusReport StatusReport object
	 */
	public static void updateOnwatchTask(StatusReport statusReport) {
		TaskListTag taskListTag = statusReport.getTaskList();
		if(taskListTag != null) {
			if(taskListTag.isFailed()) {
				OnWatchLogger.addStepLog("status report TaskListStatus: " + 
						taskListTag.getTaskListStatus());
			} else {
				//get the overall status
				TaskResultTag taskResult = taskListTag.getTaskResult();
				TaskInfoTag taskInfo = taskResult.getTaskInfo();
				int execTime = calculateExecTime(taskResult.getTaskResultStatus());
				ActOnwatchTask onwatchTask = onwatchTaskDAO.getByOnwatchTaskID(
						new Long(taskResult.getId()));
				if(onwatchTask != null) {
					onwatchTask.setCompletionDate(TimeFormatStandard.getNowMillis());
					onwatchTask.setExecutionTimeInSec(new Long(execTime));
					if(taskInfo.isSuccess()) {
						onwatchTask.markSuccess();
					} else {
						onwatchTask.markFailure();
					}
					onwatchTaskDAO.save(onwatchTask);
				} else {
					ASCLogger.warn(StatusReportHelper.class, "updateOnwatchTask",
							"Cannot find onwatchTask: {taskListId" +
							taskListTag.getId() + "},{onwatchTaskId: " + taskResult.getId() + 
							"}\n Continue..");
				}
			}
		}
	}
	
	/**
	 * Determine is the task is successfully executed
	 * @param statusReport	StatusReport object
	 * @return
	 */
	public static boolean isTaskSuccess(StatusReport statusReport) {
		boolean success = false;
		TaskListTag taskListTag = statusReport.getTaskList();
		if(taskListTag != null) {
			if(!taskListTag.isFailed()) {
				//get the overall status
				TaskResultTag taskResult = taskListTag.getTaskResult();
				TaskInfoTag taskInfo = taskResult.getTaskInfo();
				success = taskInfo.isSuccess();
			}
		}
		return success;
	}
	
	/**
	 * Get Task Id (Onwatch Task Id) from the StatusReport object
	 * @param statusReport StatusReport object
	 * @return
	 */
	public static String getTaskResultId(StatusReport statusReport) {
		String taskResultId = null;
		TaskListTag taskListTag = statusReport.getTaskList();
		if(taskListTag != null) {
			if(!taskListTag.isFailed()) {
				TaskResultTag taskResult = taskListTag.getTaskResult();
				if(taskResult != null) {
					taskResultId = taskResult.getId();
				}
			}
		}
		return taskResultId;
	}
	
	/**
	 * Get Task List status from the StatusReport object
	 * @param statusReport	StatusReport object
	 * @return
	 */
	public static String getTaskListStatus(StatusReport statusReport) {
		String taskListStatus = null;
		TaskListTag taskListTag = statusReport.getTaskList();
		if(taskListTag != null) {
			if(taskListTag.isFailed()) {
				taskListStatus = taskListTag.getTaskListStatus();
			}
		}
		return taskListStatus;
	}
	
	/**
	 * Set OnwatchTaskDAO
	 * @param onwatchTaskDAO
	 */
	public void setOnwatchTaskDAO(IOnwatchTaskDAO onwatchTaskDAO) {
		StatusReportHelper.onwatchTaskDAO = onwatchTaskDAO;
	}
	
	private static int calculateExecTime(TaskResultStatusTag taskResultStatusTag) {
		int totalSec = 0;
		ArrayList<ResultTag> results = taskResultStatusTag.getResults();
		for(ResultTag result: results) {
			totalSec += result.getTimeInSec();
		}
		return totalSec;
	}
}
